package com.quanxiaoha.weblog.web.service.impl;

import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.google.common.collect.Lists;
import com.quanxiaoha.weblog.common.domain.dos.*;
import com.quanxiaoha.weblog.common.domain.mapper.*;
import com.quanxiaoha.weblog.common.enums.FavoriteTypeEnum;
import com.quanxiaoha.weblog.common.enums.ResponseCodeEnum;
import com.quanxiaoha.weblog.common.exception.BizException;
import com.quanxiaoha.weblog.common.utils.PageResponse;
import com.quanxiaoha.weblog.common.utils.Response;
import com.quanxiaoha.weblog.web.model.vo.favorite.*;
import com.quanxiaoha.weblog.web.service.FavoriteService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import java.time.LocalDateTime;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * 收藏服务实现
 */
@Service
@Slf4j
public class FavoriteServiceImpl implements FavoriteService {

    @Autowired
    private UserFavoriteMapper userFavoriteMapper;

    @Autowired
    private FavoriteFolderMapper favoriteFolderMapper;

    @Autowired
    private FavoriteArticleFolderRelMapper favoriteArticleFolderRelMapper;

    @Autowired
    private ArticleMapper articleMapper;

    @Autowired
    private CategoryMapper categoryMapper;

    @Autowired
    private TagMapper tagMapper;

    @Autowired
    private ArticleTagRelMapper articleTagRelMapper;

    @Autowired
    private ArticleCategoryRelMapper articleCategoryRelMapper;
    
    @Autowired
    private UserMapper userMapper;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Response<?> addFavorite(AddFavoriteReqVO addFavoriteReqVO) {
        Long articleId = addFavoriteReqVO.getArticleId();
        String sessionId = addFavoriteReqVO.getSessionId();
        Integer type = addFavoriteReqVO.getType();
        Long folderId = addFavoriteReqVO.getFolderId();

        // 验证类型
        if (!isValidType(type)) {
            return Response.fail("类型参数错误");
        }

        // 检查用户是否登录（这里简化处理，实际项目中应该从上下文获取用户信息）
        if (Objects.isNull(sessionId) || sessionId.trim().isEmpty()) {
            return Response.fail("请先登录");
        }

        // 检查文章是否存在
        ArticleDO article = articleMapper.selectById(articleId);
        if (Objects.isNull(article) || article.getIsDeleted()) {
            log.warn("文章不存在或已删除, articleId: {}", articleId);
            throw new BizException(ResponseCodeEnum.ARTICLE_NOT_FOUND);
        }

        // 检查是否已收藏（包括已删除的记录）
        UserFavoriteDO existingFavorite = userFavoriteMapper.selectFavoriteByUserAndArticleIncludeDeleted(null, sessionId, articleId, type);
        if (Objects.nonNull(existingFavorite)) {
            if (!existingFavorite.getIsDeleted()) {
                // 记录存在且未删除，返回失败
                String typeName = FavoriteTypeEnum.valueOf(type).getDescription();
                log.warn("文章已{}，articleId: {}, sessionId: {}, type: {}", typeName, articleId, sessionId, type);
                return Response.fail("文章已" + typeName);
            } else {
                // 记录存在但已删除，恢复该记录
                existingFavorite.setIsDeleted(false);
                existingFavorite.setCreateTime(LocalDateTime.now());
                userFavoriteMapper.updateById(existingFavorite);
                
                // 只有收藏类型才需要关联到收藏夹
                if (Objects.equals(type, FavoriteTypeEnum.FAVORITE.getValue())) {
                    // 先删除旧的关联关系（如果存在）
                    favoriteArticleFolderRelMapper.deleteByFavoriteId(existingFavorite.getId());
                    
                    if (Objects.nonNull(folderId)) {
                        // 检查收藏夹是否存在
                        FavoriteFolderDO folder = favoriteFolderMapper.selectById(folderId);
                        if (Objects.isNull(folder) || folder.getIsDeleted()) {
                            log.warn("收藏夹不存在或已删除, folderId: {}", folderId);
                            throw new BizException(ResponseCodeEnum.FOLDER_NOT_FOUND);
                        }
                    } else {
                        // 获取或创建默认收藏夹
                        folderId = getOrCreateDefaultFolder(null, sessionId);
                    }

                    // 建立收藏记录与收藏夹的关联
                    FavoriteArticleFolderRelDO rel = FavoriteArticleFolderRelDO.builder()
                            .favoriteId(existingFavorite.getId())
                            .folderId(folderId)
                            .createTime(LocalDateTime.now())
                            .build();

                    favoriteArticleFolderRelMapper.insert(rel);
                }
                
                return Response.success();
            }
        }

        // 创建收藏记录
        UserFavoriteDO favorite = UserFavoriteDO.builder()
                .sessionId(sessionId)
                .articleId(articleId)
                .type(type)
                .createTime(LocalDateTime.now())
                .isDeleted(false)
                .build();

        userFavoriteMapper.insert(favorite);

        // 只有收藏类型才需要关联到收藏夹
        if (Objects.equals(type, FavoriteTypeEnum.FAVORITE.getValue())) {
            if (Objects.nonNull(folderId)) {
                // 检查收藏夹是否存在
                FavoriteFolderDO folder = favoriteFolderMapper.selectById(folderId);
                if (Objects.isNull(folder) || folder.getIsDeleted()) {
                    log.warn("收藏夹不存在或已删除, folderId: {}", folderId);
                    throw new BizException(ResponseCodeEnum.FOLDER_NOT_FOUND);
                }
            } else {
                // 获取或创建默认收藏夹
                folderId = getOrCreateDefaultFolder(null, sessionId);
            }

            // 建立收藏记录与收藏夹的关联
            FavoriteArticleFolderRelDO rel = FavoriteArticleFolderRelDO.builder()
                    .favoriteId(favorite.getId())
                    .folderId(folderId)
                    .createTime(LocalDateTime.now())
                    .build();

            favoriteArticleFolderRelMapper.insert(rel);
        }

        return Response.success();
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Response<?> removeFavorite(RemoveFavoriteReqVO removeFavoriteReqVO) {
        Long articleId = removeFavoriteReqVO.getArticleId();
        String sessionId = removeFavoriteReqVO.getSessionId();
        Integer type = removeFavoriteReqVO.getType();

        // 验证类型
        if (!isValidType(type)) {
            return Response.fail("类型参数错误");
        }

        // 检查用户是否登录
        if (Objects.isNull(sessionId) || sessionId.trim().isEmpty()) {
            return Response.fail("请先登录");
        }

        // 查找收藏记录
        UserFavoriteDO favorite = userFavoriteMapper.selectFavoriteByUserAndArticle(null, sessionId, articleId, type);
        if (Objects.isNull(favorite)) {
            String typeName = FavoriteTypeEnum.valueOf(type).getDescription();
            log.warn("{}记录不存在, articleId: {}, sessionId: {}, type: {}", typeName, articleId, sessionId, type);
            return Response.fail(typeName + "记录不存在");
        }

        // 删除收藏记录（逻辑删除）
        favorite.setIsDeleted(true);
        userFavoriteMapper.updateById(favorite);

        // 删除关联关系（只有收藏类型才有关联关系）
        if (Objects.equals(type, FavoriteTypeEnum.FAVORITE.getValue())) {
            favoriteArticleFolderRelMapper.deleteByFavoriteId(favorite.getId());
        }

        return Response.success();
    }

    @Override
    public Response<?> findFavoriteList(FindFavoriteListReqVO findFavoriteListReqVO) {
        String sessionId = findFavoriteListReqVO.getSessionId();
        Integer type = findFavoriteListReqVO.getType();

        // 验证类型
        if (!isValidType(type)) {
            return Response.fail("类型参数错误");
        }

        // 分页参数
        long current = findFavoriteListReqVO.getCurrent();
        long size = findFavoriteListReqVO.getSize();
        Page<UserFavoriteDO> page = new Page<>(current, size);

        // 查询收藏记录
        Page<UserFavoriteDO> favoritePage = userFavoriteMapper.selectFavoriteArticles(null, sessionId, type, page);

        List<UserFavoriteDO> favoriteRecords = favoritePage.getRecords();
        List<FindFavoriteListRspVO.FavoriteArticleRspVO> favoriteArticles = Lists.newArrayList();

        if (!CollectionUtils.isEmpty(favoriteRecords)) {
            // 批量查询文章信息
            List<Long> articleIds = favoriteRecords.stream()
                    .map(UserFavoriteDO::getArticleId)
                    .collect(Collectors.toList());

            List<ArticleDO> articles = articleMapper.selectBatchIds(articleIds);

            for (UserFavoriteDO favorite : favoriteRecords) {
                // 查找对应的文章
                ArticleDO article = articles.stream()
                        .filter(a -> Objects.equals(a.getId(), favorite.getArticleId()))
                        .findFirst()
                        .orElse(null);

                if (Objects.nonNull(article) && !article.getIsDeleted()) {
                    FindFavoriteListRspVO.FavoriteArticleRspVO favoriteArticle = convertToFavoriteArticleRspVO(favorite, article);
                    favoriteArticles.add(favoriteArticle);
                }
            }
        }

        return PageResponse.success(favoritePage, favoriteArticles);
    }

    @Override
    public Response<?> checkFavoriteStatus(Long articleId, String sessionId, Integer type) {
        // 验证类型
        if (!isValidType(type)) {
            return Response.fail("类型参数错误");
        }

        UserFavoriteDO favorite = userFavoriteMapper.selectFavoriteByUserAndArticle(null, sessionId, articleId, type);

        CheckFavoriteStatusRspVO rspVO = CheckFavoriteStatusRspVO.builder()
                .isFavorited(Objects.nonNull(favorite))
                .favoriteId(Objects.nonNull(favorite) ? favorite.getId() : null)
                .build();

        return Response.success(rspVO);
    }

    /**
     * 验证类型是否有效
     */
    private boolean isValidType(Integer type) {
        return Objects.nonNull(type) && 
               (Objects.equals(type, FavoriteTypeEnum.LIKE.getValue()) || 
                Objects.equals(type, FavoriteTypeEnum.FAVORITE.getValue()));
    }

    /**
     * 获取或创建默认收藏夹
     */
    private Long getOrCreateDefaultFolder(Long userId, String sessionId) {
        // 查找默认收藏夹
        FavoriteFolderDO defaultFolder = favoriteFolderMapper.selectDefaultFolder(userId, sessionId);

        if (Objects.isNull(defaultFolder)) {
            // 创建默认收藏夹
            defaultFolder = FavoriteFolderDO.builder()
                    .userId(userId)
                    .sessionId(sessionId)
                    .name("默认收藏夹")
                    .description("系统默认收藏夹")
                    .isDefault(true)
                    .createTime(LocalDateTime.now())
                    .updateTime(LocalDateTime.now())
                    .isDeleted(false)
                    .build();

            favoriteFolderMapper.insert(defaultFolder);
        }

        return defaultFolder.getId();
    }

    /**
     * 转换为收藏文章响应VO
     */
    private FindFavoriteListRspVO.FavoriteArticleRspVO convertToFavoriteArticleRspVO(UserFavoriteDO favorite, ArticleDO article) {
        // 查询分类
        String categoryName = null;
        ArticleCategoryRelDO categoryRel = articleCategoryRelMapper.selectOne(
                Wrappers.<ArticleCategoryRelDO>lambdaQuery()
                        .eq(ArticleCategoryRelDO::getArticleId, article.getId())
        );
        if (Objects.nonNull(categoryRel)) {
            CategoryDO category = categoryMapper.selectById(categoryRel.getCategoryId());
            if (Objects.nonNull(category)) {
                categoryName = category.getName();
            }
        }

        // 查询标签
        List<String> tags = Lists.newArrayList();
        List<ArticleTagRelDO> tagRels = articleTagRelMapper.selectList(
                Wrappers.<ArticleTagRelDO>lambdaQuery()
                        .eq(ArticleTagRelDO::getArticleId, article.getId())
        );
        if (!CollectionUtils.isEmpty(tagRels)) {
            List<Long> tagIds = tagRels.stream()
                    .map(ArticleTagRelDO::getTagId)
                    .collect(Collectors.toList());
            List<TagDO> tagDOs = tagMapper.selectBatchIds(tagIds);
            tags = tagDOs.stream()
                    .map(TagDO::getName)
                    .collect(Collectors.toList());
        }

        // 获取作者信息
        String author = "博主";
        if (Objects.nonNull(article.getUserId())) {
            UserDO userDO = userMapper.selectById(article.getUserId());
            if (Objects.nonNull(userDO)) {
                // 优先使用昵称，如果昵称为空则使用用户名
                author = (Objects.nonNull(userDO.getNickname()) && !userDO.getNickname().trim().isEmpty()) 
                        ? userDO.getNickname() 
                        : userDO.getUsername();
            }
        }
        
        return FindFavoriteListRspVO.FavoriteArticleRspVO.builder()
                .favoriteId(favorite.getId())
                .articleId(article.getId())
                .title(article.getTitle())
                .cover(article.getCover())
                .summary(article.getSummary())
                .author(author)
                .articleCreateTime(article.getCreateTime())
                .favoriteCreateTime(favorite.getCreateTime())
                .readNum(article.getReadNum().intValue())
                .categoryName(categoryName)
                .tags(tags)
                .build();
    }
}